// Base Material Interface
// (c) jimon game studio

#ifndef JEH_JEMATERIAL
#define JEH_JEMATERIAL

#include "jeTypes.h"
#include "jeStl.h"
#include "ITexture.h"
#include "IShaderMaterial.h"

namespace je
{
	namespace video
	{
		//! Material Types
		enum MaterialType
		{
			//! Solid Material
			MT_SOLID = 0,

			//! Alpha blend
			MT_ALPHABLEND = 1,

			//! Light blend
			MT_LIGHTBLEND = 2,

			//! Shade blend
			MT_SHADEBLEND = 3,

			//! Additive blend
			MT_ADDITIVEBLEND = 4
		};

		//! Base Material Interface
		class jeMaterial
		{
		public:

			//! Material Type
			MaterialType Type;

			//! Texture Array
			ITexture ** Textures;

			//! Max Using Texture Layer
			s32 MaxUsageTextureLayer;

			//! Shader Material
			IShaderMaterial * ShaderMaterial;

			//! Enable ZBuffer Test
			u1 EnableZBufferTest;

			//! Enable ZBuffer Mas
			u1 EnableZBufferMask;

			//! Constructor
			jeMaterial()
				:Type(MT_SOLID),Textures(NULL),MaxUsageTextureLayer(-1),ShaderMaterial(NULL),EnableZBufferTest(true),EnableZBufferMask(true)
			{
				JENEW_A(Textures,ITexture *,JE_MAX_MATERIAL_TEXTURES)
				for(s32 i=0;i<JE_MAX_MATERIAL_TEXTURES;i++)
					Textures[i] = NULL;
			}

			//! Destructor
			~jeMaterial()
			{
				if(ShaderMaterial)
					ShaderMaterial->Drop();

				if(Textures)
				{
					for(s32 i=0;i<=MaxUsageTextureLayer;i++)
						if(Textures[i])
							Textures[i]->Drop();
					JEDELETE_A(Textures)
				}
			}

			//! Set Texutre
			void SetTexture(ITexture * Texture,s32 TextureLayer = 0)
			{
				if(Textures[TextureLayer])
				{
					Textures[TextureLayer]->Drop();
					if(TextureLayer == MaxUsageTextureLayer)
					{
						s32 Last = -1;
						for(s32 i=0;i<MaxUsageTextureLayer;i++)
						{
							if(Textures[i])
								Last = i;
						}
						MaxUsageTextureLayer = Last;
					}
				}

				Textures[TextureLayer] = Texture;

				if(Textures[TextureLayer])
				{
					Textures[TextureLayer]->Grab();
					if(TextureLayer > MaxUsageTextureLayer)
						MaxUsageTextureLayer = TextureLayer;
				}
			}

			//! Return Texture
			inline ITexture * GetTexture(u32 TextureLayer = 0)
			{
				return Textures[TextureLayer];
			}

			//! Set Shader Material
			void SetShaderMaterial(IShaderMaterial * Material)
			{
				if(ShaderMaterial)
					ShaderMaterial->Drop();

				ShaderMaterial = Material;

				if(ShaderMaterial)
					ShaderMaterial->Grab();
			}
		};
	}
}

#endif
